From 39ac68abaff0d7b59cbe80036aac37f41ad976ec Mon Sep 17 00:00:00 2001
From: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
Date: Wed, 24 Sep 2014 13:54:15 +0100
Subject: [PATCH] Add support for uClibc

The stable-1.1 branch of freerdp fails to build when using a uClibc
toolchain because it's using functions which are not implemented in
uClibc, like eventfd_read, eventfd_write and futimes. That is causing
build failures like these ones:

../../libwinpr/synch/libwinpr-synch.so.0.1.0: undefined reference to
`eventfd_read'
../../libwinpr/synch/libwinpr-synch.so.0.1.0: undefined reference to
`eventfd_write'

../../common/libfreerdp-client.so.1.1.0: undefined reference to
`futimes'

This patch is based on this upstream patch:

  https://github.com/FreeRDP/FreeRDP/commit/5f9c36da5d5cd3c5dce49f7b32fe011cb293f9ec/

To support newer versions of uClibc and uclibc-ng this patch also includes a
backported version of upstream commit 3b7d3190a16c (Fix build with newer
uclibc versions, 2015-04-28)

Signed-off-by: Vicente Olivert Riera <Vincent.Riera@imgtec.com>
[baruch: merge in upstream commit 3b7d3190a16c]
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 CMakeLists.txt                     |  3 +++
 channels/drive/client/drive_file.c | 12 +++++++++---
 config.h.in                        |  1 +
 winpr/libwinpr/synch/event.c       | 14 ++++++++++++++
 4 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 375e2d1b6845..5b7887601aa0 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -276,6 +276,9 @@ endif()
 
 if(UNIX OR CYGWIN)
 	check_include_files(sys/eventfd.h HAVE_EVENTFD_H)
+	if (HAVE_EVENTFD_H)
+		check_symbol_exists(eventfd_read sys/eventfd.h WITH_EVENTFD_READ_WRITE)
+	endif()
 	set(X11_FEATURE_TYPE "RECOMMENDED")
 else()
 	set(X11_FEATURE_TYPE "DISABLED")
diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c
index 376b4fe74be7..b20f408aa356 100644
--- a/channels/drive/client/drive_file.c
+++ b/channels/drive/client/drive_file.c
@@ -480,7 +480,11 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
 	int status;
 	char* fullpath;
 	struct STAT st;
+#if defined(ANDROID)
 	struct timeval tv[2];
+#else
+	struct timespec tv[2];
+#endif
 	UINT64 LastWriteTime;
 	UINT32 FileAttributes;
 	UINT32 FileNameLength;
@@ -501,15 +505,17 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
 				return FALSE;
 
 			tv[0].tv_sec = st.st_atime;
-			tv[0].tv_usec = 0;
 			tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
-			tv[1].tv_usec = 0;
 #ifndef WIN32
 /* TODO on win32 */                        
 #ifdef ANDROID
+			tv[0].tv_usec = 0;
+			tv[1].tv_usec = 0;
 			utimes(file->fullpath, tv);
 #else
-			futimes(file->fd, tv);
+			tv[0].tv_nsec = 0;
+			tv[1].tv_nsec = 0;
+			futimens(file->fd, tv);
 #endif
 
 			if (FileAttributes > 0)
diff --git a/config.h.in b/config.h.in
index 2b8ec09c2afb..55c595d0e162 100755
--- a/config.h.in
+++ b/config.h.in
@@ -33,6 +33,7 @@
 #cmakedefine WITH_JPEG
 #cmakedefine WITH_WIN8
 #cmakedefine WITH_RDPSND_DSOUND
+#cmakedefine WITH_EVENTFD_READ_WRITE
 
 /* Plugins */
 #cmakedefine STATIC_CHANNELS
diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c
index 173afafb7cc9..cb3f338178d9 100644
--- a/winpr/libwinpr/synch/event.c
+++ b/winpr/libwinpr/synch/event.c
@@ -115,6 +115,20 @@ HANDLE OpenEventA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
 	return NULL;
 }
 
+#ifdef HAVE_EVENTFD_H
+#if !defined(WITH_EVENTFD_READ_WRITE)
+static int eventfd_read(int fd, eventfd_t* value)
+{
+	return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1;
+}
+
+static int eventfd_write(int fd, eventfd_t value)
+{
+	return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1;
+}
+#endif
+#endif
+
 BOOL SetEvent(HANDLE hEvent)
 {
 	ULONG Type;
-- 
1.7.1

